home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
CUGUK
/
APPLICAT
/
C034.ZIP
/
NLONG.C
< prev
next >
Wrap
Text File
|
2010-11-01
|
8KB
|
352 lines
/*
Long package amended and extended to support BDS 1.50 library
added lcomp - compare two strings (as per documentation)
ltoas - long to ascii scaled
atols - ascii to long scaled
function numbers 0,7,8 have not yet been identified
and are marked as UK1,UK3,UK4 below.
a few functions in the documentation have not been done
yet but are trivial to implement when required.
*/
#define UK1 0
#define COMP 1
#define ADD 2
#define SUB 3
#define MUL 4
#define DIV 5
#define MOD 6
#define UK3 7
#define UK4 8
/* ladd adds the addend and augend to produce a 32 bit
signed result in sum. A pointer to sum is returned. */
char *ladd(sum,addend,augend)
char sum[], addend[], augend[];
{
char *long();
return (long(ADD,sum,addend,augend));
}
/* lsub subtracts subtrahend from minuend and places the
32 bit signed difference in difference. A pointer to
difference is returned. */
char *lsub(difference,minuend,subtrahend)
char difference[], minuend[], subtrahend[];
{
char *long();
return (long(SUB,difference,minuend,subtrahend));
}
/* lmul multiplies plier and plicand together and places
the signed low order 32 bit product in product. A
pointer to product is returned. */
char *lmul(product,plier,plicand)
char product[], plier[], plicand[];
{
char *long();
return (long(MUL,product,plier,plicand));
}
/* scale must be from 0 to 9 */
char *lmuls(product,plier,plicand,scale)
char product[],plier[],plicand[]; int scale;
{
char *long();
char ten[4],five[4];
ten[3]=0x0a; ten[1]=ten[2]=ten[0]=0;
five[3]=0x05; five[1]=five[2]=five[0]=0;
long(MUL,product,plier,plicand);
/* round and scale */
while (scale--) {
long(ADD,product,product,five);
long(DIV,product,product,ten);
}
return(&product);
}
/* ldiv divides dividend by divisor and places the signed
low order 32 bits of the quotient in quotient. A
pointer to quotient is returned.
ldivs takes account of a scale when performing the
division - 0 <= scale < 10 */
char *ldiv(quotient,dividend,divisor)
char quotient[], dividend[], divisor[];
{
char *long();
return (long(DIV,quotient,dividend,divisor));
}
char *ldivs(quotient,dividend,divisor,scale)
char quotient[], dividend[], divisor[]; int scale;
{
char *long();
char ten[4];
ten[3]=0x0a; ten[1]=ten[2]=ten[0]=0;
while (scale--)
long(MUL,dividend,dividend,ten);
long(DIV,quotient,dividend,divisor);
}
/* lmod places the 31 bit positive remainder resulting
from the division of dividend by divisor into residue.
A pointer to residue is returned. */
char *lmod(residue,dividend,divisor)
char residue[], dividend[], divisor[];
{
char *long();
return (long(MOD,residue,dividend,divisor));
}
/* lneg places the 32 bit signed negative of orignum in
negnum and returns a pointer to it. */
char *lneg(negnum,orignum)
char negnum[], orignum[];
{
char *long(), work[4], i;
for (i=0; i<4; ++i) work[i]=0;
return (long(SUB,negnum,work,orignum));
}
/* lcomp returns -1,0,1 depending on result of left<right,l=r,l>r */
int lcomp(left,right)
char left[], right[];
{
return(long(COMP,left,right));
}
/* itol converts an integer to long form. A pointer
to the longform is returned. */
char *itol(longform,i)
char longform[];
int i;
{
longform[1]=longform[0]=0;
if (i<0) longform[1]=longform[0]=0xff;
longform[2]=i>>8;
longform[3]=i&0xff;
return longform;
}
/* ltoi returns a properly signed integer containing the
low order 15 bits of precision of the long integer
longint. The value of this integer is placed in i and
is returned by this function. */
ltoi(longint)
char longint[4];
{
int i;
char work[4];
for (i=0; i<4; ++i) work[i]=longint[i];
if (work[0]>127) lneg(work,work);
i=(work[2]<<8)+work[3];
if (longint[0]>127) i=-i;
return i;
}
/* atol converts the ASCII string s to a long integer
placed in longint and returns a pointer to longint.
Acceptable format for atol is: any amount of white
space followed by an optional sign followed by a string
of decimal digits. The first non-decimal digit stops
the scan. The method used is an adaptation of that
presented in Kernighan and Ritchie. */
char *atols(longint,s,scale)
char longint[]; char s[]; int scale;
{
int i, j;
char wstr[20];
char *wptr,*sptr;
sptr = &s[0];
wptr = &wstr[0];
/* white space */
while (*sptr == ' ' || *sptr == '\t')
sptr++;
/* a sign */
if (*sptr == '-' || *sptr == '+')
*wptr++ = *sptr++;
/* integral digits */
while (isdigit(*sptr))
*wptr++ = *sptr++;
/* have we got a dot */
if (*sptr == '.') {
sptr++;
while (scale--)
if (isdigit(*sptr))
*wptr++ = *sptr++;
else
*wptr++ = '0';
}
else
while (scale--)
*wptr++ = '0';
/* end of string */
*wptr++ = 0;
return(atol(longint,wstr));
}
char *atol(longint,s)
char longint[], s[];
{
char work[4], ten[4];
int i, j, n, sign;
/* form a constant.. */
ten[3]=0x0a; ten[1]=ten[2]=ten[0]=0;
/* first skip white space... */
for (i=0; s[i]==' ' || s[i]=='\n' || s[i]=='\t'; i++);
/* now get the sign... */
sign=1;
if (s[i]=='+' || s[i]=='-')
sign=(s[i++]=='+') ? 1 : -1;
/* and convert the string straightforwardly... */
for (j=0; j<4; ++j) longint[j]=0;
while (s[i]>='0' && s[i]<='9') {
for (j=0; j<4; ++j) work[j]=0;
work[3]=s[i++]-'0';
lmul(longint,ten,longint);
ladd(longint,longint,work);
}
/* not forgetting the original sign... */
if (sign==-1) lneg(longint,longint);
return longint;
}
/* ltoa converts the long integer longint to an ASCII
string which is placed in s. If longint is negative a
minus sign is prefixes the string. The algorithm used
is an adaptation of itoa presented in Kernighan and
Ritchie. */
ltoas(sptr,inlong,scale)
char *sptr; char inlong[]; int scale;
{
int i, j;
char work[20];
char *wptr,*fptr,*tptr;
/* Special case - get rid of integers */
if (scale == 0)
return(ltoa(sptr,inlong));
/* get the full string */
ltoa(work,inlong);
wptr = &work[0];
/* minimum length */
if (*wptr == '-')
j = scale + 3;
else
j = scale + 2;
i = strlen(wptr) + 1;
if (j < i)
j = i;
/* point at last digits */
fptr = &wptr[i-2];
tptr = sptr + j;
*tptr-- = 0;
while (scale--)
if ((fptr < wptr) || (*fptr == '-'))
*tptr-- = '0';
else
*tptr-- = *fptr--;
*tptr-- = '.';
if ((fptr < wptr) || (*fptr == '-'))
*tptr-- = '0';
while (fptr >= wptr)
*tptr-- = *fptr--;
return (sptr);
}
ltoa(s,inlong)
char s[], inlong[];
{
char c, work[4], ten[4], longint[4];
int i, j, k, sign;
ten[3]=0x0a; ten[1]=ten[2]=ten[0]=0;
sign=1;
for(i=0 ; i<4 ; i++) longint[i] = inlong[i];
/* check the sign... */
if (longint[0]>127) {
sign=-1;
lneg(longint,longint);
}
/* convert, generating digits backwards in s[]... */
i=0;
do {
lmod(work,longint,ten);
s[i++]=work[3]+'0';
ldiv(longint,longint,ten);
} while ((longint[0]|longint[1]|longint[2]|
longint[3])!=0);
/* postfix a minus sign if needed... */
if (sign==-1) s[i++]='-';
s[i]='\0';
/* and turn the whole thing around in place. */
k=strlen(s);
for (i=0, j=k-1; i<j; i++, j--) {
c=s[i]; s[i]=s[j]; s[j]=c;
}
return s;
}
ing around in place. */
k=strlen(s);